#include <stdio.h>
#include <stdarg.h>
#include <string.h>

#include "../ncp_log.h"
#include "grammar.h"

static def_node* g_root_node = NULL;

// Here is a solution which can avoid buffer overlow
int sscanf_chars(const char *string, const char *format, ...)
{
	char     *pValue;
	int      paramCount=0-3, ret=0, i;
	int      pArgs[16];
	va_list  arglist, saveargs;

	va_start(arglist, format);
	saveargs = arglist;
	while ( va_arg(arglist, char *)!=NULL ) {
		paramCount++;
	}
	if (paramCount>16) goto __END__;

	arglist = saveargs;
	ret = sscanf(string, format, 
		&pArgs[0],  &pArgs[1],  &pArgs[2],  &pArgs[3], 
		&pArgs[4],  &pArgs[5],  &pArgs[6],  &pArgs[7],
		&pArgs[8],  &pArgs[9],  &pArgs[10], &pArgs[11],
		&pArgs[12], &pArgs[13], &pArgs[14], &pArgs[15]);

	for (i=0; i<paramCount; i++)
	{
		pValue = va_arg(arglist, char *);
		*pValue = pArgs[i];
	}

__END__:
	va_end(arglist);
	return ret;
}

/*=======================================================*/
/*node function                                          */
/*=======================================================*/
/* create node */
def_node* grammar_create_node(def_enum_node_type node_type, def_enum enum_type, def_count parameter_count, ...)
{
	va_list        parameters;
	int            i      = 0;	
	def_node*      node   = NULL;
	char*          yytext = NULL;
		
	va_start(parameters, parameter_count);	

	if(enum_node_type_parse == node_type)
	{
		switch(enum_type)
		{
		case enum_parse_type_program:
			node = (g_root_node = va_arg(parameters, def_node*));
			break;
		case enum_parse_type_expr:
			node = va_arg(parameters, def_node*);
			break;
		case enum_parse_type_tern:
			node = va_arg(parameters, def_node*);
			break;
		}
	}

	if(enum_node_type_value == node_type)
	{
		node                               = (def_node*)malloc(sizeof(def_node));
		if(NULL == node)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
			return NULL;
		}
		node->node_type                    = node_type;
		node->node_value.value             = malloc(sizeof(def_value_node));
		node->node_value.value->value_type = enum_type;
		yytext                             = va_arg(parameters, char*);
		if(NULL == node->node_value.value || NULL == yytext)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
			fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
			return NULL;
		}
		
		switch(enum_type)
		{
		case enum_value_type_ipaddr:			
			node->node_value.value->value_value.ipaddr = malloc(sizeof(def_ipaddr));
			if(NULL == node->node_value.value->value_value.ipaddr)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				return NULL;
			}
			sscanf_chars(yytext, "%d.%d.%d.%d", 
				&node->node_value.value->value_value.ipaddr->char1, 
				&node->node_value.value->value_value.ipaddr->char2, 
				&node->node_value.value->value_value.ipaddr->char3, 
				&node->node_value.value->value_value.ipaddr->char4);
			break;
		case enum_value_type_ipaddr_area:
			node->node_value.value->value_value.ipaddr_area = malloc(sizeof(def_ipaddr_area));
			if(NULL == node->node_value.value->value_value.ipaddr_area)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				return NULL;
			}
			sscanf_chars(yytext, "%d.%d.%d.%d-%d.%d.%d.%d", 
				&node->node_value.value->value_value.ipaddr_area->ipaddr_from.char1,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_from.char2,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_from.char3,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_from.char4,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_to.char1,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_to.char2,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_to.char3,
				&node->node_value.value->value_value.ipaddr_area->ipaddr_to.char4);		
			break;
		case enum_value_type_macaddr:
			node->node_value.value->value_value.macaddr = malloc(sizeof(def_macaddr));
			if(NULL == node->node_value.value->value_value.macaddr)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				return NULL;
			}
			sscanf_chars(yytext, "%x:%x:%x:%x:%x:%x", 
				&node->node_value.value->value_value.macaddr->char1, 
				&node->node_value.value->value_value.macaddr->char2, 
				&node->node_value.value->value_value.macaddr->char3, 
				&node->node_value.value->value_value.macaddr->char4, 
				&node->node_value.value->value_value.macaddr->char5, 
				&node->node_value.value->value_value.macaddr->char6);
			break;
		case enum_value_type_macaddr_area:
			node->node_value.value->value_value.macaddr_area = malloc(sizeof(def_macaddr_area));
			if(NULL == node->node_value.value->value_value.macaddr_area)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				return NULL;
			}
			sscanf_chars(yytext, "%x:%x:%x:%x:%x:%x-%x:%x:%x:%x:%x:%x", 
				&node->node_value.value->value_value.macaddr_area->macaddr_from.char1, 
				&node->node_value.value->value_value.macaddr_area->macaddr_from.char2, 
				&node->node_value.value->value_value.macaddr_area->macaddr_from.char3, 
				&node->node_value.value->value_value.macaddr_area->macaddr_from.char4, 
				&node->node_value.value->value_value.macaddr_area->macaddr_from.char5, 
				&node->node_value.value->value_value.macaddr_area->macaddr_from.char6,
				&node->node_value.value->value_value.macaddr_area->macaddr_to.char1, 
				&node->node_value.value->value_value.macaddr_area->macaddr_to.char2, 
				&node->node_value.value->value_value.macaddr_area->macaddr_to.char3, 
				&node->node_value.value->value_value.macaddr_area->macaddr_to.char4, 
				&node->node_value.value->value_value.macaddr_area->macaddr_to.char5, 
				&node->node_value.value->value_value.macaddr_area->macaddr_to.char6);
			break;		
		case enum_value_type_number:			
			sscanf(yytext, "%d", &node->node_value.value->value_value.number);
			break;
		case enum_value_type_number_area:
			node->node_value.value->value_value.number_area = malloc(sizeof(def_number_area));
			if(NULL == node->node_value.value->value_value.number_area)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				return NULL;
			}
			sscanf(yytext, "%d-%d", 
				&node->node_value.value->value_value.number_area->number_from, 
				&node->node_value.value->value_value.number_area->number_to);
			break;
		case enum_value_type_hex:
			node->node_value.value->value_value.hex = malloc(sizeof(def_hex));
			if(NULL == node->node_value.value->value_value.hex)
			{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
				fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
				return NULL;
			}
			else
			{
				char temp[3] = {0,0,0};
				unsigned char *pValue;
				int byte_len = 0;
				int i        = 0;
				while(yytext[byte_len+++2] != '\'');
				byte_len /= 2;				
				
				node->node_value.value->value_value.hex->count = byte_len;
				node->node_value.value->value_value.hex->value = (char*)malloc(byte_len);
				if(NULL == node->node_value.value->value_value.hex->value)
				{					
					return NULL;
				}
				
				pValue = node->node_value.value->value_value.hex->value;
				for(i=0; i<byte_len; i++)
				{
					temp[0] = yytext[i*2+1];
					temp[1] = yytext[i*2+2];
					*(pValue++) = ( char )strtol(temp, NULL, 16);
				}
			}
			break;
		case enum_value_type_string:
		case enum_value_type_operation:
			break;
		}
	}

	if(enum_node_type_operation == node_type)
	{		
		node                                              = (def_node*)malloc(sizeof(def_node));
		if(NULL == node)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
			return NULL;
		}
		node->node_type                                   = node_type;
		node->node_value.operation                        = malloc(sizeof(def_operation_node));
		if(NULL == node->node_value.operation)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
			return NULL;
		}
		node->node_value.operation->operation_type        = enum_type;
		node->node_value.operation->operation_value_count = parameter_count;
		node->node_value.operation->operation_values      = malloc(sizeof(def_value_node) * parameter_count);
		if(NULL == node->node_value.operation->operation_values)
		{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_MALLOC_ERROR);
#endif
			return NULL;
		}

		for(i=0; i<parameter_count; i++)
		{
			node->node_value.operation->operation_values[i] = va_arg(parameters, def_node*);
			if(NULL == node->node_value.operation->operation_values[i])
			{
				return NULL;
			}
		}		
	}
	
	va_end(parameters);
	return node;
}

/* free node */
def_bool grammar_free_node(def_node* node)
{
	int i = 0;

	if(NULL == node)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_NULL_POINTER_ERROR);
#endif
		return def_false;

	}

	if(enum_node_type_operation == node->node_type)
	{
		switch(node->node_value.operation->operation_type)
		{
		case enum_operation_type_op_not:
		case enum_operation_type_op_and:
		case enum_operation_type_op_or:
		case enum_operation_type_op_bracket:
		case enum_operation_type_packet_data_byte:
		case enum_operation_type_packet_data_area:
		case enum_operation_type_mac_src:		
		case enum_operation_type_mac_des:
		case enum_operation_type_ip_src:		
		case enum_operation_type_ip_des:		
		case enum_operation_type_tcp_port_src:		
		case enum_operation_type_tcp_port_des:
		case enum_operation_type_tcp_data_byte:
		case enum_operation_type_tcp_data_area:
		case enum_operation_type_udp_port_src:
		case enum_operation_type_udp_port_des:
		case enum_operation_type_udp_data_byte:
		case enum_operation_type_udp_data_area:
			for(i=0; i<node->node_value.operation->operation_value_count; i++)
			{
				grammar_free_node(node->node_value.operation->operation_values[i]);
			}			
		}

		free(node->node_value.operation);
		free(node);
		return def_true;
	}

	if(enum_node_type_value == node->node_type)
	{
		switch(node->node_value.value->value_type)
		{
		case enum_value_type_ipaddr:			
			free(node->node_value.value->value_value.ipaddr);
			break;
		case enum_value_type_ipaddr_area:
			free(node->node_value.value->value_value.ipaddr_area);
			break;
		case enum_value_type_macaddr:
			free(node->node_value.value->value_value.macaddr);
			break;
		case enum_value_type_macaddr_area:
			free(node->node_value.value->value_value.macaddr_area);
			break;		
		case enum_value_type_number:					
			break;
		case enum_value_type_number_area:
			free(node->node_value.value->value_value.number_area);
			break;
		case enum_value_type_hex:
			free(node->node_value.value->value_value.hex->value);
			free(node->node_value.value->value_value.hex);
			break;
		case enum_value_type_string:		
			break;
		}

		free(node->node_value.value);
		free(node);
		return def_true;
	}
	
	return def_false;
}

/* excute node */
def_bool grammar_excute_node(def_node* node)
{	
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
	def_bool log_res;
#endif

	if(NULL == node)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_NULL_POINTER_ERROR);
#endif
		return def_false;

	}

	if(enum_node_type_operation == node->node_type)
	{
		switch(node->node_value.operation->operation_type)
		{
		case enum_operation_type_op_not:
			return !grammar_excute_node(node->node_value.operation->operation_values[0]);			
			break;
		case enum_operation_type_op_and:			
			return 
				grammar_excute_node(node->node_value.operation->operation_values[0])
				&&
				grammar_excute_node(node->node_value.operation->operation_values[1]);
			break;
		case enum_operation_type_op_or:	
			return
				grammar_excute_node(node->node_value.operation->operation_values[0])
				||
				grammar_excute_node(node->node_value.operation->operation_values[1]);
			break;
		case enum_operation_type_op_bracket:
			return 
				grammar_excute_node(node->node_value.operation->operation_values[0]);			
			break;
		case enum_operation_type_packet_data_byte:
		case enum_operation_type_packet_data_area:
		case enum_operation_type_mac_src:		
		case enum_operation_type_mac_des:
		case enum_operation_type_ip_src:		
		case enum_operation_type_ip_des:		
		case enum_operation_type_tcp_port_src:		
		case enum_operation_type_tcp_port_des:
		case enum_operation_type_tcp_data_byte:
		case enum_operation_type_tcp_data_area:
		case enum_operation_type_udp_port_src:
		case enum_operation_type_udp_port_des:
		case enum_operation_type_udp_data_byte:
		case enum_operation_type_udp_data_area:
#if LOG_LEVEL_FIV >= LOG_CUR_LEVEL
			log_res = grammar_deal_excute(node->node_value.operation);
			fprintf(g_log_io, LOG_DEAL_EXCUTE, node->node_value.operation->operation_type, log_res);
			return log_res;
#else
			return grammar_deal_excute(node->node_value.operation);	
#endif
			break;
		}

		return def_false;
	}

	if(enum_node_type_value == node->node_type)
	{
		return def_false;
	}
	
	return def_false;
}

/* deal excute */

#if LOG_LEVEL_FOR >= LOG_CUR_LEVEL
/* draw node */
def_bool grammar_draw_node(def_node* node)
{
	if(enum_node_type_operation == node->node_type)
	{
		switch(node->node_value.operation->operation_type)
		{
		case enum_operation_type_op_not:
			fprintf(g_log_io, LOG_DRAW_NOT);
			grammar_draw_node(node->node_value.operation->operation_values[0]);			
			break;
		case enum_operation_type_op_and:			
			grammar_draw_node(node->node_value.operation->operation_values[0]);			
			fprintf(g_log_io, LOG_DRAW_AND);
			grammar_draw_node(node->node_value.operation->operation_values[1]);
			break;
		case enum_operation_type_op_or:				
			grammar_draw_node(node->node_value.operation->operation_values[0]);			
			fprintf(g_log_io, LOG_DRAW_OR);
			grammar_draw_node(node->node_value.operation->operation_values[1]);
			break;
		case enum_operation_type_op_bracket:
			fprintf(g_log_io, LOG_DRAW_BRAKET_LEFT);
			grammar_draw_node(node->node_value.operation->operation_values[0]);
			fprintf(g_log_io, LOG_DRAW_BRAKET_RIGHT);
			break;
		case enum_operation_type_packet_data_byte:
		case enum_operation_type_packet_data_area:
		case enum_operation_type_mac_src:		
		case enum_operation_type_mac_des:
		case enum_operation_type_ip_src:		
		case enum_operation_type_ip_des:		
		case enum_operation_type_tcp_port_src:		
		case enum_operation_type_tcp_port_des:
		case enum_operation_type_tcp_data_byte:
		case enum_operation_type_tcp_data_area:
		case enum_operation_type_udp_port_src:
		case enum_operation_type_udp_port_des:
		case enum_operation_type_udp_data_byte:
		case enum_operation_type_udp_data_area:
			grammar_deal_draw(node->node_value.operation);	
			break;
		}

		return 0;
	}

	if(enum_node_type_value == node->node_type)
	{
		return 0;
	}
	
	return 0;
}

/* deal draw */
def_bool grammar_deal_draw(def_operation_node* operation)
{	
	int i = 0;

	switch(operation->operation_type)
	{
	case enum_operation_type_packet_data_byte:
		fprintf(g_log_io, LOG_DD_PACKET_DATA_BYTE,
				operation->operation_values[0]->node_value.value->value_value.number,
				operation->operation_values[1]->node_value.value->value_value.number);		
		break;
	case enum_operation_type_packet_data_area:
		fprintf(g_log_io, LOG_DD_PACKET_DATA_AREA,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		for(i=0; i<operation->operation_values[1]->node_value.value->value_value.hex->count; i++)
		{
			fprintf(g_log_io, LOG_DD_DATA,
				operation->operation_values[1]->node_value.value->value_value.hex->value[i]);
			if(((i % 16) == 0) && (i != 0))
			{
				fprintf(g_log_io, LOG_DRAW_N);
			}
		}
		printf("\n");
		break;
	case enum_operation_type_ip_src:
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_ipaddr)
		{
			fprintf(g_log_io, LOG_DD_IP_SRC, 
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char1,
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char2,
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char3,
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char4);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_IP_SRC_AREA,  
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char1,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char2,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char3,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char4,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char1,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char2,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char3,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char4);
		}
		break;
	case enum_operation_type_ip_des:
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_ipaddr)
		{
			fprintf(g_log_io, LOG_DD_IP_DES,  
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char1,
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char2,
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char3,
				operation->operation_values[0]->node_value.value->value_value.ipaddr->char4);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_IP_SRC_AREA, 
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char1,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char2,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char3,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_from.char4,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char1,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char2,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char3,
				operation->operation_values[0]->node_value.value->value_value.ipaddr_area->ipaddr_to.char4);
		}
		break;
	case enum_operation_type_mac_src:
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_macaddr)
		{
			fprintf(g_log_io, LOG_DD_MAC_SRC, 
				operation->operation_values[0]->node_value.value->value_value.macaddr->char1,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char2,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char3,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char4,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char5,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char6);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_MAC_SRC_AREA,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char1,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char2,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char3,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char4,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char5,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char6,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char1,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char2,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char3,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char4,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char5,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char6);
		}
		break;
	case enum_operation_type_mac_des:
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_macaddr)
		{
			fprintf(g_log_io, LOG_DD_MAC_DES,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char1,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char2,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char3,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char4,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char5,
				operation->operation_values[0]->node_value.value->value_value.macaddr->char6);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_MAC_DES_AREA,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char1,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char2,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char3,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char4,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char5,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_from.char6,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char1,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char2,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char3,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char4,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char5,
				operation->operation_values[0]->node_value.value->value_value.macaddr_area->macaddr_to.char6);
		}
		break;	
	case enum_operation_type_tcp_port_src:		
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			fprintf(g_log_io, LOG_DD_TCP_PORT_SRC,
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_TCP_PORT_SRC_AREA,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from, 
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		}
		break;
	case enum_operation_type_tcp_port_des:
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			fprintf(g_log_io, LOG_DD_TCP_PORT_DES,
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_TCP_PORT_DES_AREA,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from, 
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		}
		break;
	case enum_operation_type_tcp_data_byte:
		fprintf(g_log_io, LOG_DD_TCP_DATA_BYTE,
				operation->operation_values[0]->node_value.value->value_value.number,
				operation->operation_values[1]->node_value.value->value_value.number);		
		break;
	case enum_operation_type_tcp_data_area:
		fprintf(g_log_io, LOG_DD_TCP_DATA_AREA,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		for(i=0; i<operation->operation_values[1]->node_value.value->value_value.hex->count; i++)
		{
			fprintf(g_log_io, LOG_DD_DATA,
				operation->operation_values[1]->node_value.value->value_value.hex->value[i]);
			if(((i % 16) == 0) && (i != 0))
			{
				fprintf(g_log_io, LOG_DRAW_N);
			}
		}
		printf("\n");
		break;
	case enum_operation_type_udp_port_src:		
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			fprintf(g_log_io, LOG_DD_UDP_PORT_SRC, 
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_UDP_PORT_SRC_AREA, 
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from, 
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		}
		break;
	case enum_operation_type_udp_port_des:
		if(operation->operation_values[0]->node_value.value->value_type == enum_value_type_number)
		{
			fprintf(g_log_io, LOG_DD_UDP_PORT_DES, 
				operation->operation_values[0]->node_value.value->value_value.number);
		}
		else
		{
			fprintf(g_log_io, LOG_DD_UDP_PORT_DES_AREA,  
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from, 
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		}
		break;
	case enum_operation_type_udp_data_byte:
		fprintf(g_log_io, LOG_DD_UDP_DATA_BYTE, 
				operation->operation_values[0]->node_value.value->value_value.number,
				operation->operation_values[1]->node_value.value->value_value.number);		
		break;
	case enum_operation_type_udp_data_area:
		fprintf(g_log_io, LOG_DD_UDP_DATA_AREA,  
				operation->operation_values[0]->node_value.value->value_value.number_area->number_from,
				operation->operation_values[0]->node_value.value->value_value.number_area->number_to);
		for(i=0; i<operation->operation_values[1]->node_value.value->value_value.hex->count; i++)
		{
			fprintf(g_log_io, LOG_DD_DATA, 
				operation->operation_values[1]->node_value.value->value_value.hex->value[i]);
			if(((i % 8) == 0) && (i != 0))
			{
				fprintf(g_log_io, LOG_DRAW_N);
			}
		}
		printf("\n");
		break;
	}
	
	return 1;
}
#endif

/*=======================================================*/
/*tree function                                          */
/*=======================================================*/
/* create tree */
def_node* grammar_create_tree(char* text)
{
	if(NULL == text)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_RULE_TEXT_ERROR);
#endif		
		return NULL;
	}	

	yy_scan_string(text);

	if(0 == yyparse())
	{
		return g_root_node;
	}
	else
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_RULE_TEXT_ERROR);
#endif
		return NULL;
	}
}

/* excute tree */
def_bool grammar_excute_tree(def_node* node)
{
	if(node == NULL)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_NULL_POINTER_ERROR);
#endif
		return 0;
	}

	return grammar_excute_node(node);
}

/* free tree */
def_bool grammar_free_tree(def_node* node)
{
	if(node == NULL)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_NULL_POINTER_ERROR);
#endif
		return def_false;
	}

	return grammar_free_node(node);
}

#if LOG_LEVEL_FOR >= LOG_CUR_LEVEL
/* draw tree */
def_bool grammar_draw_tree(def_node* node)
{
	if(node == NULL)
	{
#if LOG_LEVEL_ONE >= LOG_CUR_LEVEL
		fprintf(g_log_io, LOG_NULL_POINTER_ERROR);
#endif
		return 0;
	}

	return grammar_draw_node(node);
}
#endif

